import datetime
from app.core.extensions import db


class Banner(db.Model):
    __tablename__ = 'banners'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100))
    image_url = db.Column(db.String(255), nullable=False)
    link_url = db.Column(db.String(255))
    sort = db.Column(db.Integer, default=0)
    status = db.Column(db.Integer, default=1)
    hex = db.Column(db.String(20), nullable=True, comment='颜色HEX值')
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')

    def to_dict(self):
        return {
            "id": self.id,
            "imageUrl": self.image_url,
            "url": self.link_url,
            "title": self.title,
            "sort": self.sort,
            "hex": self.hex,

        }


class Notice(db.Model):
    __tablename__ = 'notices'
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text, nullable=False)
    sort = db.Column(db.Integer, default=0)
    status = db.Column(db.Integer, default=1)
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')

    def to_dict(self):
        return {
            "id": self.id,
            "content": self.content
        }


class Article(db.Model):
    __tablename__ = 'articles'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    second_title = db.Column(db.String(200))
    url = db.Column(db.String(255), nullable=False)
    image_url = db.Column(db.String(255))
    update_time = db.Column(db.DateTime, default=datetime.datetime.now)
    is_top = db.Column(db.Integer, default=0)
    sort_number = db.Column(db.Integer, default=0)
    status = db.Column(db.Integer, default=1)
    create_time = db.Column(db.DateTime, default=datetime.datetime.now)
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')

    def to_dict(self):
        return {
            "id": str(self.id),
            "title": self.title,
            "secondTitle": self.second_title,
            "url": self.url,
            "updateTime": self.update_time.strftime('%Y-%m-%d %H:%M:%S') if self.update_time else '',
            "isTop": self.is_top,
            "sortNumber": self.sort_number
        }


# 租户模型
class Tenant(db.Model):
    __tablename__ = 'tenants'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False, comment='租户名称')
    code = db.Column(db.String(50), unique=True, nullable=False, comment='租户标识')
    app_id = db.Column(db.String(50), nullable=False, comment='微信小程序 AppID')
    admin_name = db.Column(db.String(64), nullable=False, comment='管理员账号')
    status = db.Column(db.String(20), default='active', comment='状态: active-启用，inactive-禁用，trial-试用')
    expire_date = db.Column(db.Date, nullable=True, comment='到期日期')
    remark = db.Column(db.String(255), comment='备注')
    created_at = db.Column(db.DateTime, default=datetime.datetime.now)
    updated_at = db.Column(db.DateTime, onupdate=datetime.datetime.now)

    # # 租户下的管理员关系
    # admins = db.relationship('Admin', backref='tenant', lazy='dynamic')

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'code': self.code,
            'admin_name': self.admin_name,
            'status': self.status,
            'app_id': self.app_id,
            'expire_date': self.expire_date.strftime('%Y-%m-%d') if self.expire_date else None,
            'remark': self.remark,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None,
            'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S') if self.updated_at else None
        }

    def get_app_id(self):
        """获取租户的微信小程序 AppID"""
        return self.app_id


# 权限模型
class Permission(db.Model):
    __tablename__ = 'permissions'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False, comment='权限名称')
    code = db.Column(db.String(100), unique=True, nullable=False, comment='权限标识')
    type = db.Column(db.String(20), default='button', comment='权限类型: menu-菜单权限, button-按钮权限, api-API权限')
    description = db.Column(db.String(255), comment='权限描述')
    created_at = db.Column(db.DateTime, default=datetime.datetime.now)
    updated_at = db.Column(db.DateTime, onupdate=datetime.datetime.now)
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'code': self.code,
            'type': self.type,
            'description': self.description,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None
        }


# 角色模型
class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False, comment='角色名称')
    description = db.Column(db.String(255), comment='角色描述')
    created_at = db.Column(db.DateTime, default=datetime.datetime.now)
    updated_at = db.Column(db.DateTime, onupdate=datetime.datetime.now)
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='所属租户ID')

    # 角色与权限的多对多关系
    permissions = db.relationship('Permission', secondary='role_permissions',
                                  backref=db.backref('roles', lazy='dynamic'))

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'description': self.description,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None,
            'tenant_id': self.tenant_id
        }


# 菜单模型
class Menu(db.Model):
    __tablename__ = 'menus'
    id = db.Column(db.Integer, primary_key=True)
    parent_id = db.Column(db.Integer, db.ForeignKey('menus.id'), nullable=True, comment='父菜单ID')
    title = db.Column(db.String(100), nullable=False, comment='菜单名称')
    path = db.Column(db.String(255), comment='路由路径')
    component = db.Column(db.String(255), comment='组件地址')
    icon = db.Column(db.String(50), comment='图标')
    permission = db.Column(db.String(100), comment='权限标识')
    sort = db.Column(db.Integer, default=0, comment='排序')
    hidden = db.Column(db.Boolean, default=False, comment='是否隐藏')
    created_at = db.Column(db.DateTime, default=datetime.datetime.now)
    updated_at = db.Column(db.DateTime, onupdate=datetime.datetime.now)
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')
    # 子菜单关系
    children = db.relationship('Menu', backref=db.backref('parent', remote_side=[id]), lazy='dynamic')

    def to_dict(self, include_children=True, depth=0, max_depth=5):
        result = {
            'id': self.id,
            'parent_id': self.parent_id,
            'title': self.title,
            'path': self.path,
            'component': self.component,
            'icon': self.icon,
            'permission': self.permission,
            'sort': self.sort,
            'hidden': self.hidden,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None
        }

        if include_children and depth < max_depth:
            result['children'] = [child.to_dict(include_children=True, depth=depth + 1, max_depth=max_depth) for child
                                  in self.children.order_by(Menu.sort)]
        else:
            result['children'] = []

        return result


# 角色权限关联表
class RolePermission(db.Model):
    __tablename__ = 'role_permissions'
    id = db.Column(db.Integer, primary_key=True)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'), nullable=False)
    permission_id = db.Column(db.Integer, db.ForeignKey('permissions.id'), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.datetime.now)
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')


# 管理员角色关联表
class AdminRole(db.Model):
    __tablename__ = 'admin_roles'
    id = db.Column(db.Integer, primary_key=True)
    admin_id = db.Column(db.Integer, db.ForeignKey('admins.id'), nullable=False)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.datetime.now)
    tenant_id = db.Column(db.Integer, db.ForeignKey('tenants.id'), nullable=True, comment='租户ID')


class Admin(db.Model):
    __tablename__ = 'admins'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    password_hash = db.Column(db.String(128))
    email = db.Column(db.String(120), unique=True, nullable=True)
    is_super = db.Column(db.Boolean, default=False)
    create_time = db.Column(db.DateTime, default=datetime.datetime.now)
    last_login = db.Column(db.DateTime, nullable=True)
    tenant_id = db.Column(db.Integer, nullable=True, comment='租户ID')
    is_test = db.Column(db.Boolean, default=False, comment='是否是测试账号')
    # 管理员与角色的多对多关系
    roles = db.relationship('Role', secondary='admin_roles', backref=db.backref('admins', lazy='dynamic'))

    def __init__(self, username, password_hash, email=None, is_super=False, is_test=False, tenant_id=None):
        self.username = username
        self.password_hash = password_hash  # 直接接受password_hash
        self.email = email
        self.is_super = is_super
        self.is_test = is_test
        self.tenant_id = tenant_id

    @property
    def password(self):
        raise AttributeError('密码不是可读属性')

    @password.setter
    def password(self, password):
        from app.utils.password import generate_password_hash
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        from app.utils.password import check_password_hash
        return self.password_hash == password
        # return check_password_hash(self.password_hash, password)

    @property
    def role(self):
        if self.is_super:
            return 'super_admin'
        elif self.roles and len(self.roles) > 0:
            return self.roles[0].name.lower()
        else:
            return 'editor'

    @property
    def is_tenant(self):
        return self.tenant_id is not None

    @property
    def is_test_account(self):
        """判断是否是测试账号（基于用户名）"""
        return self.username == 'test_admin'

    def get_permissions(self):
        """获取管理员的所有权限"""
        if self.is_super:
            # 超级管理员拥有所有权限
            return [p.code for p in Permission.query.all()]

        permissions = set()
        for role in self.roles:
            for permission in role.permissions:
                permissions.add(permission.code)

        return list(permissions)


class SystemLog(db.Model):
    __tablename__ = 'system_logs'
    id = db.Column(db.Integer, primary_key=True)
    admin_id = db.Column(db.Integer, db.ForeignKey('admins.id'), nullable=True)
    action = db.Column(db.String(50), nullable=False)
    details = db.Column(db.Text, nullable=True)
    ip = db.Column(db.String(50), nullable=True)
    create_time = db.Column(db.DateTime, default=datetime.datetime.now)
    admin = db.relationship('Admin', backref='logs')
    tenant_id = db.Column(db.Integer, nullable=True, comment='租户ID')


# 管理员操作日志
class AdminLog(db.Model):
    __tablename__ = 'admin_logs'
    id = db.Column(db.Integer, primary_key=True)
    admin_id = db.Column(db.Integer, db.ForeignKey('admins.id'), nullable=True)
    action = db.Column(db.String(50), nullable=False)
    details = db.Column(db.Text, nullable=True)
    ip = db.Column(db.String(50), nullable=True)
    create_time = db.Column(db.DateTime, default=datetime.datetime.now)
    admin = db.relationship('Admin', backref='admin_logs')
    tenant_id = db.Column(db.Integer, nullable=True, comment='租户ID')


class Feedback(db.Model):
    __tablename__ = 'feedbacks'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.user_id'), nullable=True)
    content = db.Column(db.Text, nullable=False)
    contact = db.Column(db.String(100), nullable=True)
    status = db.Column(db.Integer, default=0)  # 0-未处理, 1-已处理
    create_time = db.Column(db.DateTime, default=datetime.datetime.now)
    reply = db.Column(db.Text, nullable=True)
    reply_time = db.Column(db.DateTime, nullable=True)
    tenant_id = db.Column(db.Integer, nullable=True, comment='租户ID')
    user = db.relationship('User', backref='feedbacks')


class SysConfig(db.Model):
    __tablename__ = 'sys_configs'
    id = db.Column(db.Integer, primary_key=True)
    config_key = db.Column(db.String(50), unique=True, nullable=False)
    config_value = db.Column(db.Text, nullable=True)
    config_name = db.Column(db.String(100), nullable=False)
    config_type = db.Column(db.String(20), default='string')  # string, number, boolean, json
    remark = db.Column(db.String(255), nullable=True)
    create_time = db.Column(db.DateTime, default=datetime.datetime.now)
    update_time = db.Column(db.DateTime, onupdate=datetime.datetime.now)
    tenant_id = db.Column(db.Integer, nullable=True, comment='租户ID')


class PopupNotice(db.Model):
    __tablename__ = 'popup_notice'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(100), nullable=False, comment='弹窗标题')
    content = db.Column(db.Text, comment='弹窗内容')
    image_url = db.Column(db.String(255), comment='弹窗图片链接')
    link = db.Column(db.String(255), comment='跳转链接')
    start_time = db.Column(db.DateTime, nullable=False, comment='开始时间')
    end_time = db.Column(db.DateTime, nullable=False, comment='结束时间')
    enabled = db.Column(db.Boolean, default=True, nullable=False, comment='是否启用')
    created_at = db.Column(db.DateTime, default=datetime.datetime.now)
    updated_at = db.Column(db.DateTime, onupdate=datetime.datetime.now)
    tenant_id = db.Column(db.Integer, nullable=True, comment='租户ID')

    def to_dict(self):
        return {
            "id": self.id,
            "title": self.title,
            "content": self.content,
            "image_url": self.image_url,
            "link": self.link,
            "start_time": self.start_time.strftime('%Y-%m-%d %H:%M:%S') if self.start_time else None,
            "end_time": self.end_time.strftime('%Y-%m-%d %H:%M:%S') if self.end_time else None,
            "enabled": self.enabled,
            "created_at": self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None,
            "updated_at": self.updated_at.strftime('%Y-%m-%d %H:%M:%S') if self.updated_at else None,
            "tenant_id": self.tenant_id
        }
